class_name VirtualJoystick
extends Control

@export var background: TextureRect
@export var handle: TextureRect
@export var smooth_speed := 5.0

@export_group("Input Actions")
@export var action_left := "move_left"
@export var action_right := "move_right"
@export var action_up := "move_up"
@export var action_down := "move_down"

var dir: Vector2

var is_pressed: bool
var press_released: bool
var touch_finger := 0

func _process(delta: float) -> void:
	if is_pressed:
		press_released = false
		move_knob_pos()
		update_dir()
	else: 
		reset_knob_pos()
		dir = Vector2.ZERO
		if !press_released:
			press_released = true
			Input.action_release(action_left)
			Input.action_release(action_right)
			Input.action_release(action_up)
			Input.action_release(action_down)
	pass


func _input(event: InputEvent) -> void:
	if event is InputEventScreenTouch:
		var is_touching := event.pressed and get_global_rect().has_point(event.position) as bool
		
		if is_touching:
			touch_finger = event.index
			on_touched(event)
		elif event.index == touch_finger:
			on_touch_released(event)

func on_touched(event):
	is_pressed = true
	pass

func on_touch_released(event):
	is_pressed = false
	pass


func move_knob_pos():
	#print(get_distance(), ", ", get_current_max_length())
	if get_distance() <= get_current_max_length():
		handle.position = get_local_touch_pos()
	else:
		var angle := get_back_center_pos().angle_to_point(get_global_mouse_position())
		handle.position.x = (get_back_center_pos().x + cos(angle) * get_current_max_length()) - get_center_pos().x
		handle.position.y = (get_back_center_pos().y + sin(angle) * get_current_max_length()) - get_center_pos().y
	pass

func reset_knob_pos() -> void:
	handle.position = lerp(handle.position, Vector2.ZERO+size/2-handle.size/2, smooth_speed * get_process_delta_time())


func get_back_center_pos() -> Vector2:
	return position + size / 2

func get_center_pos() -> Vector2:
	return position + handle.size / 2

func get_local_touch_pos() -> Vector2: 
	return (get_global_mouse_position() - get_center_pos()) / scale.x

func get_distance() -> float:
	return get_global_mouse_position().distance_to(get_back_center_pos()) / scale.x

func get_current_max_length() -> float:
	var base_texture = background
	var curr_max_length : float
	curr_max_length = base_texture.get_size().x / 2
	return curr_max_length


var last_dir: Vector2
func update_dir() -> void:
	dir = handle.position + handle.size/2
	dir /= size/2
	dir -= Vector2.ONE
	#LogLabel.print_log(["摇杆输入方向: ", dir])
	# 发布事件
	if dir.x != 0: 
		if dir.x > 0:
			Input.action_press(action_right, dir.x)
			Input.action_release(action_left)
		else:
			Input.action_press(action_left, -dir.x)
			Input.action_release(action_right)
	else:
		Input.action_release(action_left)
		Input.action_release(action_right)
	if dir.y != 0: 
		if dir.y < 0:
			Input.action_press(action_up, -dir.y)
			Input.action_release(action_down)
		else:
			Input.action_press(action_down, dir.y)
			Input.action_release(action_up)
	else:
		Input.action_release(action_up)
		Input.action_release(action_down)
	#if dir != last_dir: 
		#last_dir = dir
		#LogLabel.print_log(["发布事件: ", 
			#action_left, ": ", Input.is_action_pressed(action_left), ", ", 
			#action_right, ": ", Input.is_action_pressed(action_right), ", ", 
			#action_up, ": ", Input.is_action_pressed(action_up), ", ", 
			#action_down, ": ", Input.is_action_pressed(action_down)
		#])
	
